// import logo from './logo.svg';
import './App.css';
import React from "react"
//创建react组件的开头字母要大写
//jsx和react是互相独立的   react可以用React.creatElemet创建html模板
// function App() {
//   //函数式组件 相当于vue3 组合式api
//   function FnHello (){
//     // return React.createElement('div',[],'hello12')
//     return <div>hello</div>
//   }
//   //单花括号 在jsx中给一个方法加<> 就会被解析成dom
//   //jsx  对数字字符串直接渲染 
//   let obj = FnHello()
//   let obj2 = <FnHello></FnHello>
//   //class式组件 相当于vue2 选项式api
//   class ClassHello extends React.Component{
//     constructor(props){
//       super(props)
//     }
//     render(){
//       return <div>classHello</div>
//     }
//   }
//   return (
//     <div className="App">
//       {obj2}
//       {obj}
//       <FnHello></FnHello>
//       <ClassHello></ClassHello>
//     </div>
//   );
// }


// //事件的绑定(class版)
// function clickEvent(a,b,el) {
//   //阻止原生事件
//   el.preventDefault()
//   //阻止冒泡
//   el.stopPropagation()
//   console.log("事件的绑定", a,b,el)
// }
// class ClassHello extends React.Component {
//   render() {
//     return <div onClick={clickEvent.bind(this)}>事件的绑定</div>
//   }
// }

// class App extends React.Component {
//   render() {
//     return (
//       <div className="App" >
//         <ClassHello></ClassHello>
//         nihao
//         <div onClick={clickEvent.bind(this,1,2)}>事件的绑定App</div>
//       </div>

//     )
//   }

// }








// //响应式数据(class类型)
// class App extends React.Component{
//   //常规写法
//   // constructor(props){
//   //   super(props)
//   //   this.state = {
//   //     a:1
//   //   }
//   // }

//   //es7写法
//   state = {
//     a:0,
//     b:{
//       a:0,
//       b:1
//     },
//     c:[1,2,3,4]
//   }

//   changestate() {
//     //此处无法触发更新
//     this.state.a++
//     this.state.c.push(4)
//     //触发响应式的方法(修改数据  触发更新)  单纯写个this.setState({}),触发更新
//     //当state有个属性是对象的时候  要修改一个属性值  其他的属性也要写全 (解决方法 : 把原对象进行展开 ... )
//     //state第二个参数 获取修改后的值
//     this.setState({
//       // a:this.state.a,
//       // b:{
//       //   a:++this.state.b.a,
//       //   ...this.state.b
//       // }
//       c:[...this.state.c]
//     },()=>{
//       console.log("获取修改后的值",this.state.a)
//     })
//   }

//   render(){
//     return (
//       <div className='App' onClick={this.changestate.bind(this)}>
//         响应式数据--{JSON.stringify(this.state)}
//       </div>
//     )
//   }
// }

// //条件渲染和循环渲染
// class App extends React.Component{
//   state={
//     show:false,
//     data:[
//       {
//         title:"a",
//         name:"zs"
//       },
//       {
//         title:"b",
//         name:"ls"
//       }
//     ]
//   }
//   changeshow=()=>{
//     this.setState({
//       show:!this.state.show
//     })
//   }
//   getobjArray = ()=>{
//     let needarray = []
//     this.state.data.forEach((item,index)=>{
//       let el = <div key={index} onClick={this.getinfo.bind(this,item)}>{item.name}---{item.title}</div>
//       needarray.push(el)
//     })
//     return needarray
//   }
//   getinfo=(item)=>{
//     console.log(item)
//   }
//   addArray = ()=>{
//     this.state.data.push({
//         title:"c",
//         name:"lww"
//     })
//     this.setState({})
//   }
//   render(){
//     return(
//       <div className='App'>
//         {/* 利用三元表达式 */}
//         条件渲染和循环渲染
//         <div onClick={this.changeshow.bind(this)}>开关按钮</div>
//         {this.state.show ? <div>开</div> : <div>关</div>}
//         <br/>
//         <div onClick={this.addArray}>列表添加</div>
//         {this.getobjArray()}
//       </div>
//     )
//   }
// }


//表单绑定(双向绑定)
// class App extends React.PureComponent{
//   state={
//     inputvalue:"123",
//     checkValue:[]
//   }
//   checkboxchange = (e)=>{
//     let arr = [...this.state.checkValue]
//     if(e.target.checked){
//       arr.push(e.target.value)
//     }else{
//       let index = arr.indexOf(e.target.value)
//       arr.splice(index,1)
//     }
//     this.setState({
//       checkValue:arr
//     },()=>{
//       // console.log(this.state.checkValue)
//     })

//   }
//   render(){
//     return(
//       <div className='App'>
//         表单绑定
//         <br/>
//         表单1：<input value={this.state.inputvalue} onInput={(e)=>{
//           let str = e.target.value
//           this.setState({
//             inputvalue:str
//           })

//         }}></input>
//         <br/>
//         输入的内容：{this.state.inputvalue}
//         <br/>
//         关于checkbox的双向绑定{this.state.checkValue}
//         <br/>
//         <input checked={this.state.checkValue.indexOf('c1') !== -1 } onChange={this.checkboxchange} type='checkbox' value="c1" name='choose'/>选择1
//         <input checked={this.state.checkValue.indexOf('c2') !== -1 } onChange={this.checkboxchange} type='checkbox' value="c2" name='choose'/>选择2
//         <input checked={this.state.checkValue.indexOf('c3') !== -1 } onChange={this.checkboxchange} type='checkbox' value="c3" name='choose'/>选择3

//       </div>
//     )
//   }
// }

//组件之间的传值和插槽


//引入子组件

// import Son from "./components/Son/Index"

// class App extends React.Component{

//   state = {
//     msg:"父组件给子组件的信息"
//   }

//   changemsg = (data)=>{
//     this.setState({
//       msg:"修改父组件的值"+data
//     })
//   }

//   render(){
//     return (
//       <div className='App'>
//         to Father
//         {/* 父传子 */}
//         {/* 插槽  具名插槽  如果是作用域插槽就直接写个方法*/}
//         {/* 子组件传递给父组件 */}
//         {/* 兄弟组件之间的传值     eventbus 或者通过父组件做媒介 */}
//         <Son changedata = {(data)=>{this.changemsg(data)}} toSon = {this.state.msg} slot2 = {<div>我是父组件的具名插槽</div>} scopslot = {(data)=>{
//           return <div>我是作用域插槽接收子组件的数据:{data}</div>
//         }}>
//           <div>父组件写在子组件的插槽</div>
//         </Son>

//       </div>
//     )
//   }
// }


// //样式的写法

// //引入css文件

// // 如何做到组件专用的css ？    如何更加方便的添加类名
// //修改css的文件名：组件名+.moudle.css   import sonstyle from './Son.module.css' 变成模块化  <div className = {sonstyle.son1}>

// //方便操作类目的库  classnames  帮助我们生成字符串

// //如果要配合css的模块化  需要映入import classnames from 'classnames/bind'


// //引入子组件
// import Cssstyle from './components/Cssstyle';


// import "./App.css"
// // import classnames from 'classnames'
// // let mymystyle = classnames({
// //   mystyle1:false,
// //   mystyle2:false
// // })

// class App extends React.Component{

//   state = {
//     classname:'mytyle1'
//   }

//   render(){
//     return <div > 
//       {/* 内联样式的写法 */}
//       <div className={"mystyle " + this.state.classname}
//       style={{
//         color:"white",
//         textAlign:"center",
//         fontSize:"30px"
//       }}
//       >样式的写法</div>
//       <br/>
//       <button onClick={this.changeclassname.bind(this)}>动态修改class</button>
//       <br/>
//       <Cssstyle></Cssstyle>
//       <br/>
//       <div className="innerstyle">和子元素相同类名的元素</div>
//     </div>
//   }

//   changeclassname = ()=>{
//     this.setState({
//       classname:"mytyle2"
//     })
//   }
// }




// //生命周期

// class App extends React.Component{
//   constructor(props){
//     super(props)
//     this.state = {
//       msg:'app'
//     }
//     console.log("第一个执行的周期")
//   }
//   // 是第二个执行的生命周期，值得注意的是这是个静态方法，传入 props ，state 。 返回值将和之前的 state 合并，作为新的 state ，传递给组件实例使用
//   //一般不写
//   static getDerivedStateFromProps (props,state){
//     console.log('第二个执行的生命周期',props,state)
//     return null
//   }
//   // shouldComponentUpdate传入新的 props ，新的 state ，和新的 context ，返回值决定是否继续执行 render 函数，调和子节点。这里应该注意一个问题，getDerivedStateFromProps 的返回值可以作为新的 state ，传递给 shouldComponentUpdate 。
//   shouldComponentUpdate(props,state){
//     //这里可以实现purcomponents的功能  判断state是否有改变在执行render (state是新的   this.state是旧的数据)
//     console.log('更新生命周期返回true确定是否执行render',state,this.state)
//     return true
//   }
//   render(){
//     // render 函数执行
//     console.log('第三个执行的生命周期')
//     return <div className='App'>
//       <button onClick={this.updateData}>更新数据</button>
//       生命周期 ---{this.state.msg}
//       </div>
//   }
//   updateData = ()=>{
//     let msg = "更新的数据"
//     this.setState({
//       msg:msg
//     })
//   }
//   componentDidMount(){
//     console.log('第四个执行的生命周期')
//   }
//   componentDidUpdate(){
//     console.log('更新生命周期完成')
//   }
//   componentWillUnmount(){
//     console.log('销毁周期')
//   }
// }



//ref和context
import Myref from './components/Myref';
// import React from 'react';
let myapp = React.createRef()
let myref = React.createRef()
//此处要记得大写哈并且要暴露出去 
export let Context1 = React.createContext("默认值")
class App extends React.Component {
  componentDidMount(){
    //refs已经弃用拉
    //createRef 用在类组件
    //useRef 用在函数组件
    //console.log(this.refs.myapp)
    console.log(myapp)
    //使用子组件的方法
    console.log(myref.current.sonfunction())
  }
  state = {
    msg:'父组件给孙子组件的消息'
  }
  render() {
    return (
      <>
        <div className='App' ref={myapp}>
          ref和context----(我是父组件)
        </div>
        {/* 进行包裹 */}
        <Context1.Provider value={this.state.msg}>
          <Myref ref={myref}></Myref>
        </Context1.Provider>
      </>
    )

  }
}



export default App;
